/**
 * Copyright (c) [2021-2021] [libbylg@126.com]
 * [lplogger] is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL
 * v2. You may obtain a copy of Mulan PSL v2 at:
 *             http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more
 * details.
 */
#ifndef LP_FORMATLIST_C_H
#define LP_FORMATLIST_C_H

#include "lp_formatlist.h"
#include "lp_list_head.h"

#include <stdlib.h>

LPEXTERN struct lp_formatlist_t* lp_new_formatlist() {
    struct lp_formatlist_t* list = (struct lp_formatlist_t*)malloc(sizeof(struct lp_formatlist_t));
    ASSERT(list != NULL);

    lp_list_head_init(&(list->head));

    return list;
}

LPEXTERN void lp_del_formatlist(struct lp_formatlist_t* list) {
    ASSERT(list != NULL);
    lp_clear_formatlist(list, NULL, NULL);
    free(list);
}

LPEXTERN void lp_clear_formatlist(struct lp_formatlist_t* list, void* context, LP_FORMATLIST_ENUMERATOR clear) {
    ASSERT(list != NULL);

    if (clear != NULL) {
        lp_list_foreach(item, n, &(list->head)) {
            struct lp_formatelem_t* elem = (struct lp_formatelem_t*)(lp_list_split((struct lp_list_head_t*)(item)));
            clear(context, elem->format);
            free(elem);
        }
    } else {
        lp_list_foreach(item, n, &(list->head)) {
            struct lp_formatelem_t* elem = (struct lp_formatelem_t*)(lp_list_split((struct lp_list_head_t*)(item)));
            free(elem);
        }
    }
}

LPEXTERN int lp_formatlist_add_tail(struct lp_formatlist_t* list, struct lp_format_t* format) {
    if (list == NULL) {
        ASSERT(false);
        return -1;
    }

    if (format == NULL) {
        ASSERT(false);
        return -1;
    }

    struct lp_formatelem_t* elem = (struct lp_formatelem_t*)malloc(sizeof(struct lp_formatelem_t));
    ASSERT(elem != NULL);
    elem->format = format;

    lp_list_add_tail((struct lp_list_head_t*)(elem), &(list->head));
    return 0;
}

LPEXTERN int lp_formatlist_add_head(struct lp_formatlist_t* list, struct lp_format_t* format) {
    if (list == NULL) {
        ASSERT(false);
        return -1;
    }

    if (format == NULL) {
        ASSERT(false);
        return -1;
    }

    struct lp_formatelem_t* elem = (struct lp_formatelem_t*)malloc(sizeof(struct lp_formatelem_t));
    ASSERT(elem != NULL);
    elem->format = format;

    lp_list_add_head((struct lp_list_head_t*)(elem), &(list->head));
    return 0;
}

LPEXTERN void lp_formatlist_foreach(struct lp_formatlist_t* list, void* context, LP_FORMATLIST_ENUMERATOR enumerator) {
    if (list == NULL) {
        ASSERT(false);
        return;
    }

    if (enumerator == NULL) {
        ASSERT(false);
        return;
    }

    lp_list_foreach(item, n, &(list->head)) {
        struct lp_formatelem_t* elem = (struct lp_formatelem_t*)(item);
        if (0 != enumerator(context, elem->format)) {
            break;
        }
    }
}

#endif // LP_FORMATLIST_C_H
